package exttable.testversioning.tablemodel;

import dbutils.DbUtils;
import dbutils.StoredQueries;
import dbutils.StringQueries;
import exttable.view.ViewAnalysis;
import exttable.view.ViewAnalysisParameter;
import exttable.view.ViewUnits;
import exttable.view.ViewVersion;
import utils.Localisation;

import javax.swing.table.AbstractTableModel;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: Admin
 * Date: Jun 17, 2010
 * Time: 11:24:17 AM
 * To change this template use File | Settings | File Templates.
 */
public class VersionViewerModel extends AbstractTableModel {

    private ViewAnalysis data;
    public static final int PARAMETER_COLUMN = 0;
    private List<ViewVersion> versions = new ArrayList<ViewVersion>();

    public VersionViewerModel(ViewAnalysis analysis) throws Exception {
        versions = getVersions(analysis);
        this.data = getData(analysis);
    }

    @Override
    public int getRowCount() {
        return data.getAnalysisParameters().get(versions.get(0)).size();
    }

    @Override
    public int getColumnCount() {
        return versions.size() + 1;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == PARAMETER_COLUMN) {
            return data.getAnalysisParameters().get(versions.get(columnIndex)).get(rowIndex);
        } else {
            ViewAnalysisParameter vap = data.getAnalysisParameters().get(versions.get(columnIndex - 1)).get(rowIndex);
            if (vap.getUnit() != null) {
                return vap.getUnit() + " (" + vap.getMinValue() + " - " + vap.getMaxValue() + ") ";
            } else {
                return Localisation.getMessage("info.noversions");
            }
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return String.class;
    }

    @Override
    public String getColumnName(int column) {
        if (column == 0) {
            return Localisation.getMessage("table.column.version");
        } else {
            return versions.get(column - 1).toString();
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    public ViewAnalysis getData() {
        return data;
    }

    private ViewAnalysis getData(ViewAnalysis analysis) throws Exception {

        Map<ViewVersion, List<ViewAnalysisParameter>> parametersMap = new HashMap<ViewVersion, List<ViewAnalysisParameter>>();
        Connection c = DbUtils.getDBConnectionGeneral();
        PreparedStatement ps = null;
        try {
            for (ViewVersion version : versions) {
                List<ViewAnalysisParameter> listParameters = new ArrayList<ViewAnalysisParameter>();
                ps = c.prepareStatement(StoredQueries.getQuery(StoredQueries.ANALYSIS_PARAMETERS_VERSION));
                ps.setInt(1, analysis.getAnalysisId());
                ps.setInt(2, analysis.getAnalysisId());
                ps.setString(3, version.getVersionId());
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {
                    ViewAnalysisParameter vap = new ViewAnalysisParameter.Build()
                            .nameRu(rs.getString("nameRu"))
                            .nameEn(rs.getString("nameEn"))
                            .nameKz(rs.getString("nameKz"))
                            .build();
                    vap.setParameterID(rs.getInt("parameterId"));
                    vap.setUnit(rs.getString("unit") == null ? null : getUnit(rs.getString("unit")));
                    vap.setMinValue(rs.getDouble("minValue"));
                    vap.setMaxValue(rs.getDouble("maxValue"));
                    listParameters.add(vap);
                }
                parametersMap.put(version, listParameters);
            }
            ViewAnalysis toReturn = new ViewAnalysis.Build()
                    .analysId(analysis.getAnalysisId())
                    .nameEn(analysis.getNameEn())
                    .nameKz(analysis.getNameKz())
                    .nameRu(analysis.getNameRu())
                    .analysName(analysis.getAnalysisName())
                    .analysisParameters(parametersMap).build();
            return toReturn;
        } catch (SQLException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        } finally {
            ps.close();
            c.close();
        }
    }

    private ViewUnits getUnit(String unitKey) throws Exception {
        ViewUnits unit = new ViewUnits();
        Connection c = DbUtils.getDBConnectionGeneral();
        StringBuilder query = new StringBuilder(StoredQueries.getQuery(StoredQueries.UNITS_RETRIVE));
        query.append(" where t1.combination_key = ?");
        PreparedStatement ps = c.prepareStatement(query.toString());
        try {
            ps.setString(1, unitKey);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                unit.setUnitKey(rs.getString("unit_key"));
                unit.setNameEn(rs.getString("name_en"));
                unit.setNameKz(rs.getString("name_kk"));
                unit.setNameRu(rs.getString("name_ru"));
            }
            return unit;
        } catch (SQLException e) {
            throw new SQLException();
        } finally {
            ps.close();
            c.close();
        }
    }

    private List<ViewVersion> getVersions(ViewAnalysis analysis) throws Exception {
        List<ViewVersion> toReturn = new ArrayList<ViewVersion>();
        Connection c = DbUtils.getDBConnectionGeneral();
        PreparedStatement ps = c.prepareStatement(StringQueries.DISTINCT_VERSION);
        try {
            ps.setInt(1, analysis.getAnalysisId());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                ViewVersion version = new ViewVersion();
                version.setVersionId(rs.getString("version"));
                version.setNameKz(rs.getString("nameKz"));
                version.setNameEn(rs.getString("nameEn"));
                version.setNameRu(rs.getString("nameRu"));
                toReturn.add(version);
            }
            return toReturn;
        } catch (SQLException e) {
            throw e;
        } finally {
            ps.close();
            c.close();
        }
    }
}
